package com.slashvision.im.chat

import android.Manifest
import android.view.LayoutInflater
import android.view.View
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Surface
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import androidx.navigation.NavHostController
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberPermissionState
import com.slashvision.im.ContextUtil
import io.openim.android.sdk.OpenIMClient
import io.openim.android.sdk.models.Message
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.math.ceil
import com.slashvision.im.R
import com.slashvision.im.SLog
import com.slashvision.im.eventbus.Bus
import com.slashvision.im.toastLong
import com.slashvision.im.ui.ComposeToolbar
import com.slashvision.im.ui.UScreen
import com.slashvision.stylist.common.eventbus.BusKey
import com.slashvision.stylist.im.RecordVoiceUtil
import java.io.File

/**
 * author : lizhenxin
 *  date  : 2021/11/24
 *  desc  :
 */

const val ROUTE_CHAT_UI = "_ROUTE_CHAT_UI_"

/**
 * 聊天页面封装
 */
@ExperimentalPermissionsApi
@ExperimentalComposeUiApi
@Composable
fun PageChat(vm: ChatViewModel, navController: NavHostController) {
    ComposeChat(
//            uiState,
        vm.currentUIState,
        onBackClick = { navController.navigateUp() },
        sendMsg = { msg ->
            vm.sendMessage(msg)
            vm.currentUIState.addMsg(msg)
        },
        onInitView = {
            vm.setConvRead()
//                vm.setConvRead(mFriendId)
        },

        onMessageClickListener = object : OnMessageClickListener {
            override fun onClick(m: Message): Boolean {
                return vm.onMessageClick(m, navController)
            }

            override fun onDoubleClick(m: Message) {

            }

            override fun onCopyClick(msg: Message) {
                vm.onCopyMessage(msg)
            }

            override fun onDeleteClick(msg: Message) {
                vm.onDeleteMessage(msg)
            }
        }
    )
}


/**
 * 聊天页面
 */
@ExperimentalPermissionsApi
@ExperimentalComposeUiApi
@Composable
fun ComposeChat(
    uiState: ChatUiState,
    onBackClick: () -> Unit,
    sendMsg: (Message) -> Unit,
    onMessageClickListener: OnMessageClickListener,
    onInitView: () -> Unit
) = UScreen {
    // 0: sending; 1: cancel send; 3: remove
    val voiceInputIndicatorState = remember { mutableStateOf(3) }


    val msgScrollstate = rememberLazyListState()
    val scope = rememberCoroutineScope()

    val lifecycleOwner = LocalLifecycleOwner.current

    val permissionState = rememberPermissionState(permission = Manifest.permission.RECORD_AUDIO)


    val onVoiceLongPressListener =
        getVoiceLongPress(voiceInputIndicatorState, scope, sendMsg)


    LaunchedEffect(key1 = Unit) {
        /*Bus.with<MutableList<PicSessionItem>>(BusKey.SEND_IMAGE).register(lifecycleOwner) {
            SLog.d(TAG_IM, "收到图片消息")
            it.forEach {
                SLog.d(TAG_IM, "收到图片，路径为：${it.path}")
                val msg =
                    OpenIMClient.getInstance().messageManager.createImageMessageFromFullPath(it.path)
                sendMsg(msg)
                scope.launch {
                    msgScrollstate.scrollToItem(0)
                }
            }
        }

        Bus.with<VideoInfo>(BusKey.SEND_VIDEO).register(lifecycleOwner) {
            SLog.d(TAG_IM, "收到视频消息")
            SLog.d(TAG_IM, "收到视频，路径为：${it.videoPath}")

            val msg =
                OpenIMClient.getInstance().messageManager.createVideoMessageFromFullPath(
                    it.videoPath,
                    it.videoType,
                    it.duration,
                    it.snapshotPath
                )
            sendMsg(msg)
            scope.launch {
                msgScrollstate.scrollToItem(0)
            }
        }*/

        when {
            permissionState.hasPermission -> {

            }
            permissionState.shouldShowRationale || !permissionState.permissionRequested -> {
                permissionState.launchPermissionRequest()
            }
            else -> {
                ContextUtil.getContext().toastLong("未授予录音权限，无法使用聊天功能")
                onBackClick()
            }
        }
    }



    Surface(modifier = Modifier.fillMaxSize()) {

        LaunchedEffect(key1 = Unit) {
            onInitView()
        }

        ConstraintLayout(modifier = Modifier
            .fillMaxSize()
            .onGloballyPositioned {
            }) {
            val rToolbar = createRef()
            val rMsgList = createRef()
            val rInput = createRef()

            // toolbar
            ComposeToolbar(
                title = uiState.friendName,
                isBackIconVisible = true,
                onBackClick = onBackClick,
                layoutModifier = Modifier.constrainAs(rToolbar) {
                    top.linkTo(parent.top)
                    centerHorizontallyTo(parent)
                })

            // 消息列表
            MsgList(
                modifier = Modifier.constrainAs(rMsgList) {
                    top.linkTo(rToolbar.bottom)
                    centerHorizontallyTo(parent)
                    bottom.linkTo(rInput.top)
                    width = Dimension.fillToConstraints
                    height = Dimension.fillToConstraints
                },
                msgScrollstate,
                uiState.msgList,
                uiState.friendId,
                onClickAvatar = {

                },
                onMessageClickListener = onMessageClickListener
            )

            // 用户输入区域
            UserInput(
                modifier = Modifier.constrainAs(rInput) {
                    centerHorizontallyTo(parent)
                    bottom.linkTo(parent.bottom)
                },
                onSendText = {
                    sendMsg(OpenIMClient.getInstance().messageManager.createTextMessage(it))
                    scope.launch { msgScrollstate.scrollToItem(0) }
                },
                onVoiceLongPressListener
            )


            // 语音输入指示器
            voiceInputIndicatorState.value.takeIf { it != 3 }?.let {
                VoiceInputIndicator(
                    voiceInputIndicatorState.value == 0
                ) {
                    onVoiceLongPressListener.onStopLongPress()
                }
            }

            /*// 长按消息的操作
            msgOptionState.value.takeIf { it }?.let {
                longPressedMsg?.let { msg ->
                    MsgOption(
                        msg = msg,
                        coordinates = longPressedCoordinates ?: Offset.Zero,
                        options = onMsgLongPressOptionListener
                    ) {
                        msgOptionState.value = false
                    }
                }
            }*/
        }
    }
}


fun getVoiceLongPress(
    voiceInputIndicatorState: MutableState<Int>,
    scope: CoroutineScope,
    sendMsg: (Message) -> Unit
) = object : VoiceOnLongPressListener {

    override fun onStartLongPress(offset: Offset) {
        voiceInputIndicatorState.value = 0
        scope.launch { RecordVoiceUtil.startRecord() }
    }

    override fun onMoveOutside(isOutside: Boolean) {
        if (isOutside) {
            voiceInputIndicatorState.value = 1
        } else {
            voiceInputIndicatorState.value = 0
        }
    }

    override fun onStopLongPress() {
        if (voiceInputIndicatorState.value == 0) {
            // 确认录音, 发送消息
            scope.launch {
                val info = RecordVoiceUtil.stopRecord()
                SLog.d(TAG_IM_VOICE, "时长：${info.duration}")
                launch(Dispatchers.Main) {
                    with(
                        OpenIMClient.getInstance().messageManager.createSoundMessageFromFullPath(
                            info.path,
                            ceil(info.duration / 1000f).toLong()
                        )
                    ) {
                        sendMsg(this@with)
                    }
                }
            }
        } else if (voiceInputIndicatorState.value == 1) {
            // 取消录音
            scope.launch {
                RecordVoiceUtil.cancelRecord()
            }
        }
        voiceInputIndicatorState.value = 3
    }
}